// ++++++++++++++++++++++++++++++++++++++++
// 《零基础Go语言算法实战》源码
// ++++++++++++++++++++++++++++++++++++++++
// Author:廖显东（ShirDon）
// Blog:https://www.shirdon.com/
// Gitee:https://gitee.com/shirdonl/goAlgorithms.git
// Buy link :https://item.jd.com/14101229.html
// ++++++++++++++++++++++++++++++++++++++++

package main

import (
	"fmt"
	"sync"
)

// 散列表
type HashTable struct {
	items map[int]Value
	lock  sync.RWMutex
}

// 键
type Key interface{}

// 值
type Value interface{}

// 具有值 v 和键 k 的项目进入散列表
func (ht *HashTable) Put(k Key, v Value) {
	ht.lock.Lock()
	defer ht.lock.Unlock()
	i := hash(k)
	if ht.items == nil {
		ht.items = make(map[int]Value)
	}
	ht.items[i] = v
}

// 从散列表中删除键为 k 的项
func (ht *HashTable) Remove(k Key) {
	ht.lock.Lock()
	defer ht.lock.Unlock()
	i := hash(k)
	delete(ht.items, i)
}

// 从散列表中获取键为 k 的项
func (ht *HashTable) Get(k Key) Value {
	ht.lock.RLock()
	defer ht.lock.RUnlock()
	i := hash(k)
	return ht.items[i]
}

// 返回散列表元素的数量
func (ht *HashTable) Size() int {
	ht.lock.RLock()
	defer ht.lock.RUnlock()
	return len(ht.items)
}

// 生成时间复杂度为 O(n) 的字符串
func hash(k Key) int {
	key := fmt.Sprintf("%s", k)
	h := 0
	for i := 0; i < len(key); i++ {
		h = 31*h + int(key[i])
	}
	return h
}

func main() {
	hashTable := HashTable{}
	for i := 1; i < 5; i++ {
		hashTable.Put(fmt.Sprintf("key%d", i), fmt.Sprintf("value%d", i))
		value2 := hashTable.Get("key2")
		fmt.Println(value2)
	}
}

//$ go run hashTable.go
//<nil>
//value2
//value2
//value2
